package forums.service;

import java.util.List;

import javax.annotation.security.RolesAllowed;

import org.apache.log4j.Logger;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.Assert;

import forums.dao.ForumDao;
import forums.dao.MessageDao;
import forums.model.Forum;
import forums.model.Message;

/*
 * Author       :       Willie Wheeler and John Wheeler
 * Book         :       'Spring In Practice' [Book written by Willie Wheeler and John Wheeler]
 */
@Service
public class ForumServiceImpl implements ForumService, InitializingBean {
	
	@SuppressWarnings("unused")
	private static final Logger log = Logger.getLogger(ForumServiceImpl.class);
	
	@Autowired
	private ForumDao forumDao;
	
	@Autowired
	private MessageDao messageDao;
	
	@Autowired
	private ForumFilter forumFilter;
	
	@Autowired
	private ForumListFilter forumListFilter;
	
	
	// ========================================================================
	// Dependency injection methods
	// ========================================================================
	
	public void setForumDao(ForumDao forumDao) {
		this.forumDao = forumDao;
	}
	
	public void setMessageDao(MessageDao messageDao) {
		this.messageDao = messageDao;
	}
	
	public void setForumFilter(ForumFilter forumFilter) {
		this.forumFilter = forumFilter;
	}
	
	public void setForumListFilter(ForumListFilter forumListFilter) {
		this.forumListFilter = forumListFilter;
	}

	public void afterPropertiesSet() throws Exception {
		Assert.notNull(forumDao, "forumDao required");
		Assert.notNull(messageDao, "messageDao required");
		Assert.notNull(forumFilter, "forumFilter required");
		Assert.notNull(forumListFilter, "forumListFilter required");
	}
	
	
	// ========================================================================
	// Service methods
	// ========================================================================
	
	@RolesAllowed({ "IS_AUTHENTICATED_REMEMBERED" })
	public String getAccountInfo() {
		return "This shows we hit ForumServiceImpl.account()";
	}
	
	@RolesAllowed({ "ROLE_ADMIN" })
	public String getAdminInfo() {
		return "This shows we hit ForumServiceImpl.admin()";
	}
	
	public List<Forum> getForums() {
		
		// Copy the forum list and also the individual forums, applying the
		// message filter to remove unauthorized messages.
		// This approach doesn't scale well with the number of messages but
		// it illustrates one way of returning "clean" domain objects to the
		// controller. (I.e. the controller doesn't itself have to apply
		// access controls to the forum messages.)
		log.debug("Applying ForumListFilter to forum list");
		List<Forum> orig = forumDao.readForums();
		List<Forum> copy = forumListFilter.filter(orig);
		return copy;
	}
	
	public Forum getForum(Long id) {
		Assert.notNull(id, "id required");
		
		// Copy the forum and then apply the message filter to remove
		// unauthorized messages.
		// This approach doesn't scale well with the number of messages but
		// it illustrates one way of returning "clean" domain objects to the
		// controller. (I.e. the controller doesn't itself have to apply
		// access controls to the forum messages.)
		log.debug("Applying ForumFilter to forum");
		Forum orig = forumDao.readForum(id);
		Forum copy = forumFilter.filter(orig);
		return copy;
	}
	
	@RolesAllowed({ "IS_AUTHENTICATED_ANONYMOUSLY", "AFTER_ACL_READ" })
	public Message getMessage(Long id) {
		Assert.notNull(id, "id required");
		return messageDao.readMessage(id);
	}
}
